Fix S1854 FP: Throw should connect to outer catch#9528
Fix S1854 FP: Throw should connect to outer catch#9528mary-georgiou-sonarsource merged 2 commits intomasterfrom
Conversation
8354430 to
a4a64cf
Compare
| AddPredecessorsOutsideRegion(finallyBlock); | ||
| } | ||
| } | ||
| if (block.IsEnclosedIn(ControlFlowRegionKind.Catch) && block.Successors.FirstOrDefault(x => x.Semantics == ControlFlowBranchSemantics.Rethrow) is { }) |
There was a problem hiding this comment.
| if (block.IsEnclosedIn(ControlFlowRegionKind.Catch) && block.Successors.FirstOrDefault(x => x.Semantics == ControlFlowBranchSemantics.Rethrow) is { }) | |
| if (block.IsEnclosedIn(ControlFlowRegionKind.Catch) && block.Successors.FirstOrDefault(x => x.Semantics == ControlFlowBranchSemantics.Rethrow) is not null) |
It's probably an FN for T0007.
sebastien-marichal
left a comment
There was a problem hiding this comment.
LGTM!
We discussed it together and it seems good for me.
I only added a comment about is not null usage
Tim-Pohlmann
left a comment
There was a problem hiding this comment.
LGTM only cosmetic suggestions.
| { | ||
| var tryRegion = block.EnclosingRegion(ControlFlowRegionKind.TryAndCatch).NestedRegion(ControlFlowRegionKind.Try); | ||
| foreach (var catchBlock in tryRegion.ReachableHandlers() | ||
| .Where(x => x.Kind == ControlFlowRegionKind.Catch && x != block.EnclosingRegion && x.FirstBlockOrdinal > block.Ordinal) |
There was a problem hiding this comment.
| .Where(x => x.Kind == ControlFlowRegionKind.Catch && x != block.EnclosingRegion && x.FirstBlockOrdinal > block.Ordinal) | |
| .Where(x => x.Kind == ControlFlowRegionKind.Catch && x.FirstBlockOrdinal > block.Ordinal) |
The middle condition is already covered by the last condition.
| foreach (var catchBlock in tryRegion.ReachableHandlers() | ||
| .Where(x => x.Kind == ControlFlowRegionKind.Catch && x != block.EnclosingRegion && x.FirstBlockOrdinal > block.Ordinal) | ||
| .SelectMany(x => x.Blocks(Cfg))) |
There was a problem hiding this comment.
I would separate this into an extra variable. foreach with multiple lines is always awkward to read.
| { | ||
| var code = """ | ||
| var value = 100; | ||
| try{ |
| AddPredecessorsOutsideRegion(finallyBlock); | ||
| } | ||
| } | ||
| if (block.IsEnclosedIn(ControlFlowRegionKind.Catch) && block.Successors.FirstOrDefault(x => x.Semantics == ControlFlowBranchSemantics.Rethrow) is { }) |
There was a problem hiding this comment.
| if (block.IsEnclosedIn(ControlFlowRegionKind.Catch) && block.Successors.FirstOrDefault(x => x.Semantics == ControlFlowBranchSemantics.Rethrow) is { }) | |
| if (block.IsEnclosedIn(ControlFlowRegionKind.Catch) && block.Successors.Any(x => x.Semantics == ControlFlowBranchSemantics.Rethrow)) |
|
|
| AddPredecessorsOutsideRegion(finallyBlock); | ||
| } | ||
| } | ||
| if (block.IsEnclosedIn(ControlFlowRegionKind.Catch) && block.Successors.Any(x => x.Semantics == ControlFlowBranchSemantics.Rethrow)) |
There was a problem hiding this comment.
What about Throw semantics? All the UTs have throw, but throw new Excetion("Whaaat?", ex) should behave the same
There was a problem hiding this comment.
fixed here #9530
Thanks @sebastien-marichal
|
|
||
| private void BuildBranchesNestedCatchRethrow(BasicBlock block) | ||
| { | ||
| var reachableHandlers = block.EnclosingRegion(ControlFlowRegionKind.TryAndCatch).NestedRegion(ControlFlowRegionKind.Try).ReachableHandlers(); |
There was a problem hiding this comment.
Doesn't ReachableHandlers also connect back to it's own Catch in this case? Or more precisely, all neighboring catches too? That would be wrong
There was a problem hiding this comment.
@pavel-mikula-sonarsource I'm after asking for x.FirstBlockOrdinal > block.Ordinal) - all the catch with greater ordinal that the one I'm in.
Isn't that working?
var reachableHandlers = block.EnclosingRegion(ControlFlowRegionKind.TryAndCatch).NestedRegion(ControlFlowRegionKind.Try).ReachableHandlers();
foreach (var catchBlock in reachableHandlers.Where(x => x.Kind == ControlFlowRegionKind.Catch && x.FirstBlockOrdinal > block.Ordinal).SelectMany(x => x.Blocks(Cfg)))
{}Also not sure what you mean neighbouring catches :/
There was a problem hiding this comment.
Try
Catch Ex As IOException
Throw 'You are here, with your block.Ordinal
Catch Ex As FormatException
'This is a neighbour that you don't want to connect to. And it has FirstBlockOrdinal > block.Ordinal
End TryThere was a problem hiding this comment.
Go escape, you'd need to store your TryAndCatch region, and be bigger than its LastBlockOrdinal
There was a problem hiding this comment.
Got It!
I'm opening a PR to fix this.
There was a problem hiding this comment.



Fixes #9468